package com.weicong.library;

import android.content.Context;
import android.database.DataSetObserver;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * 可循环滑动的ViewPager
 */
public class CycleViewPager extends ViewPager {

    private InnerPagerAdapter mAdapter;

    public CycleViewPager(Context context) {
        super(context);
        setOnPageChangeListener(null);
    }

    public CycleViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOnPageChangeListener(null);
    }

    @Override
    public void setAdapter(PagerAdapter adapter) {
        mAdapter = new InnerPagerAdapter(adapter);
        super.setAdapter(mAdapter);
        setCurrentItem(0);
    }

    @Override
    public void setCurrentItem(int item) {
        int index = item;
        if (item >= 0 && item < mAdapter.getOldCount()+1) {
            index++;
        }
        super.setCurrentItem(index);
    }

    public void setOnPageChangeListener(OnPageChangeListener listener) {
        super.setOnPageChangeListener(new InnerOnPageChangeListener(listener));
    }

    private static class InnerPagerAdapter extends PagerAdapter {

        private PagerAdapter mOldAdapter;

        public InnerPagerAdapter(PagerAdapter adapter) {

            mOldAdapter = adapter;
            mOldAdapter.registerDataSetObserver(new DataSetObserver() {

                @Override
                public void onChanged() {
                    notifyDataSetChanged();
                }

                @Override
                public void onInvalidated() {
                    notifyDataSetChanged();
                }

            });
        }

        @Override
        public int getCount() {
            return mOldAdapter.getCount() + 2;
        }

        private int getOldCount() {
            return mOldAdapter.getCount();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return mOldAdapter.isViewFromObject(view, object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            if(position == 0) {
                position = mOldAdapter.getCount() - 1;
            } else if(position == mOldAdapter.getCount() + 1) {
                position = 0;
            } else {
                position -= 1;
            }
            return mOldAdapter.instantiateItem(container, position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            mOldAdapter.destroyItem( container, position, object);
        }
    }

    private class InnerOnPageChangeListener implements OnPageChangeListener {

        private OnPageChangeListener mListener;
        private int position;

        public InnerOnPageChangeListener(OnPageChangeListener listener) {
            mListener = listener;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            if (mListener != null) {
                mListener.onPageScrolled(position-1, positionOffset, positionOffsetPixels);
            }
        }

        @Override
        public void onPageSelected(int position) {
            this.position = position;

            if (mListener != null) {
                int realPosition = position - 1;
                if (position == 0) {
                    realPosition = mAdapter.getOldCount() -1;
                } else if (position == mAdapter.getOldCount() + 1) {
                    realPosition = 0;
                }
                mListener.onPageSelected(realPosition);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (mListener != null) {
                mListener.onPageScrollStateChanged(state);
            }
            if(state == ViewPager.SCROLL_STATE_IDLE) {
                if(position == mAdapter.getCount() - 1) {
                    setCurrentItem(1, false);
                }
                else if(position == 0) {
                    setCurrentItem(mAdapter.getCount() - 2, false);
                }
            }
        }
    }
}
